/*(C) Copyright

    This file is part of GastosMovil.
    
    GastosMovil is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    GastosMovil is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with GastosMovil.  If not, see <http://www.gnu.org/licenses/>.
    
    Autor: Antonio Cristóbal Álvarez Abellán -> acabellan@gmail.com
    
    */

package deeloco.android.gastos.Movil.plus;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import deeloco.android.gastos.Movil.plus.R;
import deeloco.android.gastos.Movil.plus.tarifas;
import deeloco.android.gastos.Movil.plus.broadcast.avisoEstadoTelefono;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.LinearLayout.LayoutParams;

import com.android.dataframework.DataFramework;
import com.android.dataframework.Entity;
import com.google.android.apps.analytics.*;

import android.view.GestureDetector.SimpleOnGestureListener;


public class gastoMovil extends ListActivity implements OnClickListener{
    /** Called when the activity is first created. */
	private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private static final int SWIPE_MARGEN_ANULAR_Y = 60;
    private static boolean swipeHorizontal=false;
    private GestureDetector gestureDetector;
    private ProgressDialog pd;
    
    /**
     * @var cont Contexto de la actividad
     */
    private final Context cont = this;
		
	private static final int FACTURA = Menu.FIRST;
	private static final int ESTADISTICAS = Menu.FIRST+1;
	private static final int INICIO = Menu.FIRST+2;
    
    private static final int RETURN_PREFERENCES_AJUSTES = 1;
    private static final int RETURN_PREFERENCES_TARIFAS=2;
    
    private descargar_fichero ficheroServidor;
    private static final String TARIFAS_RETORNO = "tarifas_retorno";
    //private static final String TAG = "GastosMóvil";
    private double iva=1.18;
    String path="/sdcard/gastosmovil/datosTarifas.xml";
    int totalRegistros=0;
    private double costeLlamadas=0;
    private double costeSMS=0;
    int numLlamadas=0;
    private Cursor c;
    private int mesListado; //Atributo privado donde se almacena el mes que se quiere listar. Cambiara cuando arrastre a la derecha o la izquierda
    private int mesListadoPreferencias; //Atributo privado donde se almacena el mes seleccionado en ajustes
    private ListView listallamadas;
    private int mesPrimero;
    private int mesUltimo;
    
    private List<IconoYTexto> listaInvertida = new ArrayList<IconoYTexto>();
    GastosPorNumero gpn=new GastosPorNumero();
    GastosPorHora gph=new GastosPorHora();
    ValoresPreferencias vp=new ValoresPreferencias(this);
    private tarifas ts=new tarifas();
    ProgressDialog dialog;
  
    CosteLlamadas cl;
    
    public static GoogleAnalyticsTracker tracker;
    
    //private GestureDetector gestureScanner;


    //******************** AQUI ***************************

    public boolean onCreateOptionsMenu(Menu menu){
    	menu.add(Menu.NONE, FACTURA, 0, R.string.mn_factura).setIcon(android.R.drawable.ic_menu_edit);
    	menu.add(Menu.NONE, ESTADISTICAS, 0, R.string.mn_estadisticas).setIcon(android.R.drawable.ic_menu_agenda);
    	menu.add(Menu.NONE, INICIO, 0, R.string.mn_inicio).setIcon(android.R.drawable.ic_menu_preferences);
    	return true;
    }
    
    @Override
    public void onCreate(Bundle icicle) {
    	this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        super.onCreate(icicle);
        
        gestureDetector = new GestureDetector(new MyGestureDetector());
        
        setContentView(R.layout.main);
        
        //pd = ProgressDialog.show(this, "", getString(R.string.calculando_llamadas), true,true);
        pd=new ProgressDialog(this);
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pd.setMessage(getString(R.string.calculando_llamadas));
        
        if (vp.getcosteConIVA())
        	iva=vp.getPreferenciasImpuestos();
        else
        	iva=1.00; //Sin IVA
        
        /* Cargamos los valores de las tarifas */
        try
        {
        	ts.cargarTarifas(); //QUITAR
	        if (vp.getOperadora().equals("SinOperadora"))
	        {
	        	//Toast.makeText(getBaseContext(),"Sin Operadora",Toast.LENGTH_LONG).show();
	        	//Dialogo de selección de operadora
	        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle(getString(R.string.mn_operador));
				builder.setSingleChoiceItems(R.array.operadoras,-1, new DialogInterface.OnClickListener() {
				    public void onClick(DialogInterface dialog, int item) {
				        //Meter la operadora seleccionada en preferencias
				    	vp.guardarPreferences("listOperadora", getResources().getStringArray(R.array.operadoras)[item]);
				    	dialog.cancel();
				    	//Descargamos las tarifas
				    	if (!vp.getOperadora().equals("SinOperadora"))
				    	{
	 		        	   	ficheroServidor=new descargar_fichero(getApplicationContext(), getString(R.string.tarifasPre_url), getString(R.string.tarifasPre_pre)+vp.getOperadora()+getString(R.string.tarifasPre_ext), getString(R.string.tarifasPre_path));
	 		        	   	Log.d("AlertDialog","URL="+ficheroServidor.getURL()+ficheroServidor.getNombreFichero());
	 		        	   	switch (ficheroServidor.download())
	 		           		{
	 		           		case 1:
	 		           			Toast.makeText(getApplicationContext(),getString(R.string.msg_descarga_masTarde),Toast.LENGTH_LONG).show();
	 		       				break;
	 		           		case 2:
	 		           			Toast.makeText(getApplicationContext(),getString(R.string.msg_descarga_sinConexion),Toast.LENGTH_LONG).show();
	 		           			break;
	 		           		default:
	 		           			Toast.makeText(getApplicationContext(),getString(R.string.msg_descarga_ok),Toast.LENGTH_LONG).show();
	 		           			break;
	 		           		}
				    	}				    	
				    }
				});
				AlertDialog alert = builder.create();
				alert.show();
	        }
	        
	        
	        //Log.d("Gastos Móvil", "Primer Mes="+vp.primerUltimoMesConLlamadas()[0]);
	        mesPrimero=FunGlobales.mesAnterior(vp.primerUltimoMesConLlamadas()[0]);
	        mesUltimo=FunGlobales.mesPosterior(vp.primerUltimoMesConLlamadas()[1]);
	        //Log.d("Gastos Móvil", "Último Mes="+vp.primerUltimoMesConLlamadas()[1]);
	        
	        mesListadoPreferencias=vp.getPreferenciasMes();
	        mesListado=vp.getPreferenciasMes();

	        //ANTES SE COMPROBABA AQUÍ SI TENIA TARIFA POR DEFECTO O NO
        	
	        cl=new CosteLlamadas(this,handler,mesListado);
	        cl.start();
	        
	        //Cargamos las librerias DataFramework
	        try {
	            DataFramework.getInstance().open(cont, "deeloco.android.gastos.Movil.plus");
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	        
	        List<Entity> categories = DataFramework.getInstance().getEntityList("operadoras","omv=0");
	        Log.d("NUMEROS DE OPERADORAS VIRTUALES",""+categories.size());
	        Iterator<Entity> iter = categories.iterator();
	        while (iter.hasNext()) {
	            Entity ent = (Entity)iter.next();
	            Log.d("OPERADORA ", ent.getString("nombre"));
	        }

        }
        catch (Exception e)
        {
        	//Si el error se produce porque no existe el fichero xml, hay que crearlo.
        	//Tambien hay que crear el directorio
        	
        	System.out.println("ERROR:"+e.toString()+" ("+e.hashCode()+")");
        }

        //Fin de la carga
        
        tracker = GoogleAnalyticsTracker.getInstance();
        tracker.startNewSession("UA-1630192-4", 30, this);
        tracker.trackPageView("/gastosMovil");
        
        //gestureScanner = new GestureDetector((android.view.GestureDetector.OnGestureListener) this);
        
        // Configurar el listener para touch para la vista listview principal
        View mainview = (View) findViewById(android.R.id.list);
        mainview.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        });
        
        // Configurar el listener para touch para la vista listview principal
        View mainview2 = (View) findViewById(android.R.id.empty);
        mainview2.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        });


    }
    
    //Selector de opciones del menu
	public boolean onOptionsItemSelected (MenuItem item) {
		
		Bundle extras = new Bundle();
        switch(item.getItemId()) {
                 
        case FACTURA:
        	//showDialog(DIALOG_ACERCADE);
        	Intent iFactura = new Intent(getBaseContext(), simulacionFactura.class);
        	extras = new Bundle();
        	extras.putSerializable("tarifas", ts);
        	//Log.d(TAG,"Coste llamadas="+costeLlamadas);
        	extras.putDouble("costeLlamadas", costeLlamadas);
        	extras.putDouble("costeSMS", costeSMS);
        	iFactura.putExtras(extras);
        	startActivity(iFactura);
        	break;
        case INICIO:
        	//showDialog(DIALOG_ACERCADE);
			Intent i = new Intent(getBaseContext(), Inicio.class);
			extras=new Bundle();
			extras.putBoolean("delListadoLlamadas", true);
			i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//			i.setFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
			i.putExtras(extras);
        	startActivity(i);
        	finish();
        	break;

        case ESTADISTICAS:
        	//TextView tv_Numllamadas= (TextView) findViewById(R.id.txtNumLlamadas);
        	//String numLlamadas=tv_Numllamadas.getText().toString();
        	if (numLlamadas==0)
        	{
        		Toast.makeText(getBaseContext(),R.string.mensaje_noexistellamadas,Toast.LENGTH_LONG).show();
        		break;
        	}
        	gpn.ordenaGastos();
        	gph.ordenaGastos();
        	//Intent ii = new Intent(getBaseContext(), GastosPorNumeroActivity.class);
        	Intent ii = new Intent(getBaseContext(), Estadisticas.class);
        	ArrayList<String> numeros=new ArrayList <String>();
        	ArrayList<String> gastos=new ArrayList <String>();
        	ArrayList<String> horas=new ArrayList <String>();
        	ArrayList<String> gastos2=new ArrayList <String>();
        	ArrayList<String> numeros2=new ArrayList <String>();
        	ArrayList<String> duracion=new ArrayList <String>();
        	
        	String total= FunGlobales.redondear(costeLlamadas+costeSMS,2)+"";
        	
        	//Preparamos los datos estadísticos de gastos por numero
        	numeros=(ArrayList<String>) gpn.getNumeros();
        	//CAMBIAR EL ROLLO ESTE, POR UNA FUNCIÓN EN LA CLASE CORRESPONDIENTE QUE ME DEVUELVA UN ARRALIST DE STRING
        	Object ObjGastos[]=gpn.getGastos().toArray();
        	for (Object x:ObjGastos){
        		gastos.add(""+x);
        	}
        	
        	//Preparamos los datos estadísticos de gastos por horas
        	horas=(ArrayList<String>) gph.gethoras();
        	//CAMBIAR EL ROLLO ESTE, POR UNA FUNCIÓN EN LA CLASE CORRESPONDIENTE QUE ME DEVUELVA UN ARRALIST DE STRING
        	Object ObjGastos2[]=gph.getGastos().toArray();
        	for (Object x:ObjGastos2){
        		gastos2.add(""+x);
        	}
        	
        	//Preparamos los datos estadísticos de duración por numero
        	gpn.ordenaDuracion();
        	numeros2=(ArrayList<String>) gpn.getNumeros();
        	//CAMBIAR EL ROLLO ESTE, POR UNA FUNCIÓN EN LA CLASE CORRESPONDIENTE QUE ME DEVUELVA UN ARRALIST DE STRING
        	Object ObjDuracion[]=gpn.getDuracion().toArray();
        	for (Object x:ObjDuracion){
        		duracion.add(""+x);
        	}
        	
        	
        	//Estadísticas gastos por numero
        	ii.putExtra("total",total);
        	ii.putExtra("Numeros", numeros);
        	ii.putExtra("Gastos",gastos);
        	//Estadísticas gastos por hora
        	ii.putExtra("Horas", horas);
        	ii.putExtra("Gastos2",gastos2);
        	//Estadísticas duración por numero
        	String totalSegundos=ts.getSegConsumidosMes()+"";
        	ii.putExtra("totalSegundos",totalSegundos);
        	ii.putExtra("Numeros2", numeros2);
        	ii.putExtra("Duracion",duracion);
        	
        	extras = new Bundle();
        	extras.putSerializable("tarifas", ts);
        	ii.putExtras(extras);
        	startActivity(ii);
        	break;
        }
        
        return true;
	}
	
    //***************************************************
	// FUNCIONES
	//***************************************************
    
    //--- Retorna el número de SMS enviados
    private int getNumSMS_send()
    {
		int retorno=0;
		int mes=vp.getPreferenciasMes();
		
       //Cursor c;
       if (mes==0)
       {
           try
           {
               c=this.getContentResolver().query(Uri.parse("content://sms/sent"), null, null, null, null);
               this.startManagingCursor(c);
               retorno=c.getCount();
               //c.close();
           }
           catch (Exception e)
           {
               System.out.println("* Excepción: "+e.toString());
           }
       }
       else
       {
       /*Vamos a hacer una consulta de un mes concreto*/
    	/*De momento, para las pruebas, estamos utilizando 2009, pero hay que utilizar el año en curso, el mes, ... */
    	   
    	   int valorIncioMes=vp.getPreferenciasInicioMes();
    	   Date hoy=new Date();
    	   int anyo=hoy.getYear()+1900;
    	   int mesActual=hoy.getMonth()+1;
    	   if (mesActual<mes)
    	   {
    		   anyo--;
    	   }
           Calendar c1=new GregorianCalendar(anyo,mes-1,valorIncioMes,0,0);
           Calendar c2=new GregorianCalendar(anyo,mes,valorIncioMes,0,0);
           
           Date d1=new Date();
           Date d2=new Date();
           d1=c1.getTime();
           d2=c2.getTime();

           try
           {
        	   c=this.getContentResolver().query(Uri.parse("content://sms/sent"), null, null, null, null);
               this.startManagingCursor(c);
               c.moveToFirst();
               int iDate=c.getColumnIndex("date");
               if (c.isFirst())
               {
            	   do{
            		   long dateCol =c.getLong(iDate);
            		   //System.out.println("SMS con fecha: "+dateCol+"<<>>"+c.getLong(iDate));
            		   if (dateCol<d2.getTime() && dateCol>d1.getTime())
            		   {
            			   retorno++;
            		   }
            		   
            	   } while (c.moveToNext());
               }
               //c.close();
           }
           catch (Exception e)
           {
               System.out.println("* Excepción: "+e.toString());
           }
           
       }
		
        return retorno;
    }
    
    //***************************************************
	// FUNCIÓN PRINCIPAL
	//***************************************************
   
    public void listado (){
    	//List<IconoYTexto> lista = new ArrayList<IconoYTexto>();

    	listaInvertida.clear();
    	gpn.clear(); //limpiamos los gastos por numero (gpn)
    	gph.clear();

		AdaptadorListaIconos ad2 = new AdaptadorListaIconos(cont,listaInvertida);
        setListAdapter(ad2);
        listaInvertida=cl.getListaInvertida();
		AdaptadorListaIconos ad = new AdaptadorListaIconos(cont,listaInvertida);
        setListAdapter(ad);
       
               
    	double totalEstLlamadas=cl.getTotalEstablecimiento();
    	int mes=cl.getMes();
    	numLlamadas=cl.getNumLlamadas();
    	gpn=cl.getGpn();
    	gph=cl.getGph();
    	ts=cl.getTs();
    	int numSMS=0;
    	int numSMSGratis=0;
        
        costeLlamadas=cl.getTotalCosteLlamadas();
        
        //Resumen de datos del mes seleccionado
        String textoMes="";
        if (mesListado>0) 
        {
        	String meses[] = getResources().getStringArray(R.array.listaMeses);
        	textoMes=meses[mesListado+1];
        	textoMes=FunGlobales.periodo(meses, mesListado+1, vp.getPreferenciasInicioMes(),false);
        }
        
        //LinearLayout lyt_cabRegistro=(LinearLayout) findViewById(R.id.lytCabResumen);
        //TextView tv_cabResumen=(TextView) findViewById(R.id.cabResumen);
        
        //Mostrando los datos en la cabecera de resumen de datos
        
        //tv_cabResumen.setText(R.string.cabDatos);

        //Mostrando los datos de minutos llamadas en la cabecera de registro de llamadas
        
        LinearLayout linear=(LinearLayout) findViewById(R.id.lytResumenMesDia);
        linear.removeAllViewsInLayout();
        
        //
        
  	  	
  	  	//LLAMADAS
  	  	TextView txtLlamadas = new TextView(this,null,android.R.attr.textAppearanceSmall);
  	  	txtLlamadas.setTextSize(15);
  	  	txtLlamadas.setTypeface(Typeface.MONOSPACE);
  	  	txtLlamadas.setTextColor(0xff000000);
	  	linear.addView(txtLlamadas, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
	  	
	  	//SMS
  	  	TextView txtSMS = new TextView(this,null,android.R.attr.textAppearanceSmall);
  	  	txtSMS.setTextSize(15);
  	  	txtSMS.setTextColor(0xff000000);
  	  	txtSMS.setTypeface(Typeface.MONOSPACE);
  	  	linear.addView(txtSMS, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
  	  	
  	  	//Separador
  	  	ImageView separador1 = new ImageView(this);
  	  	separador1.setImageDrawable(getResources().getDrawable(android.R.drawable.divider_horizontal_bright));
  	  	separador1.setPadding(0, 5, 0, 5);
  	  	linear.addView(separador1,  new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

	  	//TARIFAS
	  	TextView txtTarifas = new TextView(this,null,android.R.attr.textAppearanceSmall);
	  	txtTarifas.setTextSize(15);
	  	txtTarifas.setTextColor(0xff000000);
	  	txtTarifas.setTypeface(Typeface.MONOSPACE);
	  	linear.addView(txtTarifas, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
	  	
    	String datosMes="";
    	String datosDia="";
    	int numLineasMes=0;
    	int numLineasDia=0;

		datosMes+=getString(R.string.res_mes)+"\n";
		datosMes+="------------\n";
		datosDia+="\n"+getString(R.string.res_dia)+" "+cl.getFechaControl()+"\n";
		datosDia+="-----------------------\n";
		numLineasMes+=2;
		numLineasDia+=3;
		
    	for (int i=0;i<ts.numTarifas();i++)
    	{
    		String nombreTarifa=ts.getTarifas().get(i).getNombre();

    		if (nombreTarifa.length()>28)
    		{
    			datosMes+=" "+nombreTarifa.substring(0, 28)+".\n";
    			datosDia+=" "+nombreTarifa.substring(0, 28)+".\n";
    		}	
    		else
    		{
    			datosMes+=" "+nombreTarifa+"\n";
    			datosDia+=" "+nombreTarifa+"\n";
    		}
    		
    		//Datos mensual
    		
    		if (ts.getTarifas().get(i).getLimite()>0)
    		{
    			//Tiene limite mensual Html.fromHtml("<font color='red'>@</font>")
    			
   				datosMes+="  * "+(ts.getTarifas().get(i).getSegConsumidosLimiteMes()/60)+"m. "+(ts.getTarifas().get(i).getSegConsumidosLimiteMes()%60)+"s.|"+getString(R.string.res_limite_mes)+" "+ts.getTarifas().get(i).getLimite()+"m.\n";
        		datosMes+="  * "+(ts.getTarifas().get(i).getSegConsumidosMes()-ts.getTarifas().get(i).getSegConsumidosLimiteMes())/60+"m. "+(ts.getTarifas().get(i).getSegConsumidosMes()-ts.getTarifas().get(i).getSegConsumidosLimiteMes())%60+"s.|"+getString(R.string.res_fuera_limite)+"\n";
        		numLineasMes+=3;
        		if (mes==vp.getPreferenciasMes())
        			vp.guardarPreferences(ts.getTarifas().get(i).getNombre()+"_segConsumidosLimiteMes", ts.getTarifas().get(i).getSegConsumidosLimiteMes());
        		//vp.guardarPreferences(ts.getTarifas().get(i).getNombre()+"_segConsumidosMes", ts.getTarifas().get(i).getSegConsumidosMes());
    		}
    		else
    		{
    			datosMes+="  * "+(ts.getTarifas().get(i).getSegConsumidosMes()/60)+"m. "+(ts.getTarifas().get(i).getSegConsumidosMes()%60)+"s.|"+getString(R.string.res_sin_limite)+"\n";
    			numLineasMes+=2;
    			if (mes==vp.getPreferenciasMes())
    				vp.guardarPreferences(ts.getTarifas().get(i).getNombre()+"_segConsumidosLimiteMes", -1); //-1, no tiene Límite mensual
    			
    			//Log.d("gastosmovil.java","CM:"+ts.getTarifas().get(i).getSegConsumidosMes());
    		}
    		if (mes==vp.getPreferenciasMes())
    		{
    			vp.guardarPreferences(ts.getTarifas().get(i).getNombre()+"_segConsumidosMes", ts.getTarifas().get(i).getSegConsumidosMes());
    			vp.guardarPreferences(ts.getTarifas().get(i).getNombre()+"_costeMes", ""+FunGlobales.redondear(ts.getTarifas().get(i).getCosteMes()*iva,2));
    			Log.d("gastosMovil.java","COSTE MES DE LA TARIFA "+ts.getTarifas().get(i).getNombre()+" ES "+FunGlobales.redondear(ts.getTarifas().get(i).getCosteMes()*iva,2));
    		}
    		
    		//Datos del último día
    		if (ts.getTarifas().get(i).getLimiteDia()>0)
    		{
    			//Tiene limite mensual
        		datosDia+="  * "+(ts.getTarifas().get(i).getSegConsumidosLimiteDia()/60)+"m. "+(ts.getTarifas().get(i).getSegConsumidosLimiteDia()%60)+"s.|"+getString(R.string.res_limite_dia)+" "+ts.getTarifas().get(i).getLimiteDia()+"m.\n";
        		datosDia+="  * "+(ts.getTarifas().get(i).getSegConsumidosDia()-ts.getTarifas().get(i).getSegConsumidosLimiteDia())/60+"m. "+(ts.getTarifas().get(i).getSegConsumidosDia()-ts.getTarifas().get(i).getSegConsumidosLimiteDia())%60+"s.|"+getString(R.string.res_fuera_limite)+"\n";
        		numLineasDia+=3;
        		//Log.d("gastosmovil.java","CLM:"+ts.getTarifas().get(i).getSegConsumidosLimiteMes()+" CM:"+ts.getTarifas().get(i).getSegConsumidosMes()+" LM:"+ts.getTarifas().get(i).getSegConsumidosLimiteMes());
        		//tv_cabRegistro.setText(ts.getTarifas().get(i).getNombre()+":"+getString(R.string.Gastado)+" "+(totalSegundosLimite/60)+" m. "+(totalSegundosLimite%60)+" s. "+ getString(R.string.Limite)+" "+limite+" m.");//TEXTO
        		//tv_cabRegistro.setText(ts.getTarifas().get(i).getNombre().subSequence(0, 10)+":"+getString(R.string.Gastado)+" "+(ts.getTarifas().get(i).getSegConsumidosMes()/60)+" m. "+(ts.getTarifas().get(i).getSegConsumidosMes()%60)+" s. "+ getString(R.string.Limite)+" "+ts.getTarifas().get(i).getLimite()+" m.");//TEXTO
    		}
    		else
    		{
    			datosDia+="  * "+(ts.getTarifas().get(i).getSegConsumidosDia()/60)+"m. "+(ts.getTarifas().get(i).getSegConsumidosDia()%60)+"s.|"+getString(R.string.res_sin_limite)+"\n";
    			numLineasDia+=2;
    			//Log.d("gastosmovil.java","CM:"+ts.getTarifas().get(i).getSegConsumidosMes());
    		}
    		
    		
    	}
    	txtTarifas.setLines(numLineasMes+numLineasDia);
    	txtTarifas.setText(datosMes+datosDia);
    	
    	
  	  	//Separador
  	  	ImageView separador2 = new ImageView(this);
  	  	separador2.setImageDrawable(getResources().getDrawable(android.R.drawable.divider_horizontal_bright));
  	  	separador2.setPadding(0, 5, 0, 5);
  	  	linear.addView(separador2,  new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
	  	
	  	//Duración media por llamada
    	TextView txtMediaLlamadas = new TextView(this,null,android.R.attr.textAppearanceSmall);
    	txtMediaLlamadas.setTextSize(15);
    	txtMediaLlamadas.setTextColor(0xff000000);
    	txtMediaLlamadas.setTypeface(Typeface.MONOSPACE);
	  	linear.addView(txtMediaLlamadas, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
	  	if (numLlamadas>0)
	  		txtMediaLlamadas.setText(getString(R.string.txtDuracionMedia)+FunGlobales.segundosAHoraMinutoSegundo(ts.getSegConsumidosMes()/numLlamadas));
	  	else
	  		txtMediaLlamadas.setText(getString(R.string.txtDuracionMedia));
	  	
	  	//Porcentaje establecimiento de llamada
    	TextView txtEstablecimiento = new TextView(this,null,android.R.attr.textAppearanceSmall);
    	txtEstablecimiento.setTextSize(15);
    	txtEstablecimiento.setTextColor(0xff000000);
    	txtEstablecimiento.setTypeface(Typeface.MONOSPACE);
	  	linear.addView(txtEstablecimiento, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        //-- Porcentaje del establecimiento de llamadas
        totalEstLlamadas=totalEstLlamadas/numLlamadas;
        txtEstablecimiento.setText(getString(R.string.res_establecimiento)+FunGlobales.redondear(totalEstLlamadas,0)+"%");
        
        
        //Número de destinos
    	TextView txtNumDestinos = new TextView(this,null,android.R.attr.textAppearanceSmall);
    	txtNumDestinos.setTextSize(15);
    	txtNumDestinos.setTextColor(0xff000000);
    	txtNumDestinos.setTypeface(Typeface.MONOSPACE);
	  	linear.addView(txtNumDestinos, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        //-- Porcentaje del establecimiento de llamadas
        //totalEstLlamadas=totalEstLlamadas/numLlamadas;
	  	txtNumDestinos.setText(getString(R.string.res_destinos)+gpn.longitud());
        
        //Numero de llamadas, coste de las llamadas
        txtLlamadas.setText(getString(R.string.res_llamadas) +" ("+numLlamadas+")..."+FunGlobales.redondear(costeLlamadas*iva,2)+FunGlobales.monedaLocal());
        

        //Calculamos el coste de los SMS
        numSMS=getNumSMS_send();
        numSMSGratis=vp.getPreferenciasSMSGratuitos();
        if (numSMS>numSMSGratis)
        	costeSMS=FunGlobales.redondear(vp.getPreferenciasTarifaSMS(),2)*(numSMS-numSMSGratis); //Mas SMS enviados que los gratuitos
        else
        	costeSMS=0; //Se han enviados menos SMS que los que hay gratuitos
        
        txtSMS.setText(getString(R.string.res_mensajes)+" ("+numSMS+")..."+FunGlobales.redondear(costeSMS*iva,2)+FunGlobales.monedaLocal());
        //Log.d("gastosMovil","coste+sms="+FunGlobales.redondear(costeLlamadas+costeSMS,2));
        
        //MOntamos el literal que se va ha presentar en el desplegable
        TextView txtMes=(TextView) findViewById(R.id.txtPersiana);
  	  	txtMes.setText(getString(R.string.cabDatos) +" "+textoMes+" ("+FunGlobales.redondear((costeLlamadas+costeSMS)*iva,2)+FunGlobales.monedaLocal()+")");
  	  	//Guardamos los datos de coste del mes para todas las tarifas
  	  	if (mes==vp.getPreferenciasMes())
  	  	{
  	  		vp.guardarPreferences("costeTotalMes", ""+FunGlobales.redondear((costeLlamadas+costeSMS)*iva,2));
  	  		Log.d("gastosMovil.java","COSTE TOTAL MES="+FunGlobales.redondear((costeLlamadas+costeSMS)*iva,2));
  	  	}
  	  	//Montamos la señal de estado
  	  	ImageView imgEstado=(ImageView) findViewById(R.id.imagePersianaEstado);
  	  	//Log.d("gastosMovil.java",""+ts.getEstadoLimite());
  	  	switch (ts.getEstadoLimite())
  	  	{
  	  	case 0: //Imagen vacia
  	  		imgEstado.setImageDrawable(null);
  	  		break;
  	  	case 1: //Imagen verde
  	  		imgEstado.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_online));
  	  		break;
  	  	case 2: //Imagen roja
  	  		imgEstado.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_busy));
  	  		break; 
  	  	}
  	  	

        //Hay que invertir la lista de llamadas, para presentarlo en pantalla y que apareccan
        //listaInvertida=lista;
        //for (int a=lista.size()-1;a>=0;a--)
        //	listaInvertida.add(lista.get(a));
        //if (lista.size()>0)
        //	listaInvertida.add(new IconoYTexto(vp.getColor("Transparente"), " "," ", " "," ",0.0));
        //dialog.dismiss();
        
        //AdaptadorListaIconos ad = new AdaptadorListaIconos(this,listaInvertida);
        //setListAdapter(ad);
        
        /*Añadir menu contextual */
        
        listallamadas=(ListView) this.findViewById(android.R.id.list);

        
        registerForContextMenu(listallamadas); //--- Registrar el menu contextual sobre el listview listallamadas

    } //-- Fin de la función principal
    
// MANEJADORES DE EVENTOS    
    
    //--- Menú contextual
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
    	super.onCreateContextMenu(menu, v, menuInfo);
    		AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
    	  	menu.setHeaderTitle(R.string.mnctx_titulo);
    	  	ArrayList <tarifa> tarifas=ts.getTarifas();
    	  	//Log.d("gastosMovil","Telefono=["+info.position+"]");
    	  	
    	  	if (!(listaInvertida.get(info.position).telefono.trim().equals("")))
    	  	{	
    	  		//Se ha seleccionado una llamada
	    	  	for (int a=0;a<tarifas.size();a++)
	    	  	{
	    	  		//La tarifa por defecto no debe aparecer en el menú contextual
	    	  		if (!tarifas.get(a).getDefecto())
	    	  		{
	    	  			//Log.d(TAG,"Pertenece "+listaInvertida.get(info.position).telefono+" a "+tarifas.get(a).getNombre()+" -- "+tarifas.get(a).pertenece(listaInvertida.get(info.position).telefono));
	    	  			if (tarifas.get(a).pertenece(listaInvertida.get(info.position).telefono))
	    	  			{
	        	  			//Ya está en esa tarifa. Hay que darle opción de eliminar
	    	  				menu.clear();
	    	  				menu.add(0, tarifas.get(a).getIdentificador(), 0, "Eliminar de "+tarifas.get(a).getNombre());
	    	  				break;
	    	  			}
	    	  			
	        	  		else
	        	  			//Añadimos la tarifa al menú contextual
	        	  			menu.add(0, tarifas.get(a).getIdentificador(), 0, "Añadir a "+tarifas.get(a).getNombre());
	    	  		}
	    	  	}
	    	  	if (menu.size()==0)
	    	  	{
	    	  		Toast.makeText(getApplicationContext(), "No existen tarifas seleccionable.", Toast.LENGTH_SHORT).show();
	    	  	}
    	  	}
    	  	else
    	  	{
    	  		//Se ha seleccionado el resumen del día
    	  		//LO añadimos a los días festivos
    	  		String fechaSeleccionada=listaInvertida.get(info.position).fecha.substring(0, 10).trim();
    	  		if (vp.esFestivo(fechaSeleccionada))
    	  		{
    	  			//Es festivo
    	  			vp.eliminarFestivo(fechaSeleccionada);
    	  			Toast.makeText(getApplicationContext(), fechaSeleccionada + " eliminado de festivos.", Toast.LENGTH_SHORT).show();
    	  		}
    	  		else
    	  		{
    	  			//No es festivo
    	  			vp.incluirFestivo(fechaSeleccionada);
    	  			Toast.makeText(getApplicationContext(), fechaSeleccionada + " añadido a festivos.", Toast.LENGTH_SHORT).show();
    	  		}
    	  		//listado(mesListado);
    	  		pd = ProgressDialog.show(this, "", getString(R.string.calculando_llamadas), true,true);
    	        cl=new CosteLlamadas(this,handler,mesListado);
    	        cl.start();
    	  		
    	  	}
    }
    
    //--- Eventos del menu contextual
    public boolean onContextItemSelected(MenuItem item) {
    	  AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    	  
    	  //REVISAR. 
    	  tarifa t=ts.getTarifa(item.getItemId());
    	  String tlf=listaInvertida.get(info.position).telefono;
    	  
    	  if (t.pertenece(tlf))
    		  //Eliminar
    		  t.deleteNumero(tlf);
    		  //listado(mesListado);
    	  else
    		  //Añadir
    		  t.addNumero(tlf);
//    		  listado(mesListado);
    	  ts.guardarTarifas();
    	  pd = ProgressDialog.show(this, "", getString(R.string.calculando_llamadas), true,true);
	      cl=new CosteLlamadas(this,handler,mesListado);
	      cl.start();
    	  return true;
    	  
    	}
    
  //--- Eventos de devolución de parámetros de preferencias.class
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
    	super.onActivityResult(requestCode, resultCode, data);
    	//Log.v("Prueba", "RESULTADO(reques/result/OK)="+requestCode+"/"+resultCode+"/"+Activity.RESULT_OK+"/"+Activity.RESULT_CANCELED);
    	switch (requestCode)
    	{
    	case RETURN_PREFERENCES_AJUSTES:
    		break;
		case RETURN_PREFERENCES_TARIFAS:
			break;
    	}
    }
    
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();	
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		//Cerramos las librerias DataFramework
		DataFramework.getInstance().close();
		try
		{
			c.close();
			tracker.dispatch();
			tracker.stopSession();
			
			//Actualizamos el widget
    		actualizarWidget aw= new actualizarWidget(getApplicationContext(),R.layout.widget);
    		RemoteViews updateView = aw.buildUpdate();
    		ComponentName myComponentName = new ComponentName(getApplicationContext(), widgetProvider.class);
    		AppWidgetManager manager = AppWidgetManager.getInstance(getApplicationContext());
    		manager.updateAppWidget(myComponentName, updateView);

		}
		catch (Exception e)
		{
		
		}
		//Intent forceUpIntent = new Intent(getBaseContext(), widgetProvider.UpdateService.class);
        //getBaseContext().startService(forceUpIntent);
	}
		
	//Mobaloo
	public void didFailToReceiveAd() {
		// TODO Auto-generated method stub
		Log.d("gastosMovil", "Fallo en la carga de la publicidad AdMob");
		
	}

	//Mobaloo
	public void didReceiveAd() {
		// TODO Auto-generated method stub
		Log.d("gastosMovil", "AdMob OK");
		
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}

//gesture  

    class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
	    //Intent intent = new Intent(gastoMovil.this.getBaseContext(), gastoMovil.class);

            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MARGEN_ANULAR_Y) 
            {
            	//Log.d("Gastos Móvil", "Swip vertical ("+e1.getY()+","+e2.getY()+")");
                return false;
            }
        	
            // right to left swipe
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY && Math.abs(e1.getY() - e2.getY()) < SWIPE_MARGEN_ANULAR_Y) 
            {
            	//Log.d("Gastos Móvil", "Swip horizontal ("+e1.getY()+","+e2.getY()+") -> "+Math.abs(e1.getY() - e2.getY()));
            	
            	swipeHorizontal=true;
        		mesListado=FunGlobales.mesPosterior(mesListado);
        		if (mesListado==mesUltimo)
        		{
        			Toast.makeText(getApplicationContext(),"No hay llamadas para el mes siguiente.",Toast.LENGTH_LONG).show();
        			mesListado=FunGlobales.mesAnterior(mesListado);
        		}
        		else
        		{
            		//listado(mesListado);
        	        cl=new CosteLlamadas(cont,handler,mesListado);
        	        cl.start();
        		}
            	
        		return true;
        		
    	    // right to left swipe
            }  
            else 
            	if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY && Math.abs(e1.getY() - e2.getY()) < SWIPE_MARGEN_ANULAR_Y) 
            	{
            		//Log.d("Gastos Móvil", "Swip horizontal ("+e1.getX()+","+e2.getX()+") -> "+Math.abs(e1.getY() - e2.getY()));
            		
            		swipeHorizontal=true;
            		mesListado=FunGlobales.mesAnterior(mesListado);
            		if (mesListado==mesPrimero)
            		{
            			Toast.makeText(getApplicationContext(),"No hay llamadas para el mes anterior.",Toast.LENGTH_LONG).show();
            			mesListado=FunGlobales.mesPosterior(mesListado);
            		}
            		else
            		{
            			//listado(mesListado);
            	        cl=new CosteLlamadas(cont,handler,mesListado);
            	        cl.start();
            		}
            		
            		return true;
            	}
 
            return false;
        }

        
    }

	/**
	 * Manejador del thread
	 */
	private Handler handler=new Handler()
	{
		public void handleMessage(Message m)
		{
			int total=m.arg1; //total de registros
			int registro=m.arg2; //registro actual procesado
			if (registro==0)
			{
				if (total==0) 
				{
					listado();
					pd.dismiss();
				}
				else
				{
					pd.setMax(total);
					pd.show();
				}
			}
			else
			{
				if (registro>=(total))
				{
					listado();
					pd.dismiss();
				}
				else
				{
					pd.setProgress(registro);
				}
			}
			
		}
	};
	
	public void onClick(DialogInterface arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}
	
	public void enlazaDeeloco(View v)
	{
		Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_BROWSABLE);
        intent.setData(Uri.parse("http://gastosmovil.simahuelva.es/index.html"));
        startActivity(intent);
	}
	
}
